from flask import Blueprint, request, send_file
import pandas as pd
from io import BytesIO

from util.PasswordEncoder import encrypt_password,decrypt_password
from entity.Response import success,error,authority
from entity.User import User
from entity.Log import Log
from db import db

import jwt
import datetime

jwt_secret_key = 'rubber'
DEFAULT_PASSWORD = '123456'
RESULT_PATH = './controller/LocalResult/'

loginController = Blueprint('loginController',__name__)

"""
用户注册
"""
@loginController.route('/register',methods=['POST'])
def register():
    username = request.get_json().get('username')
    password = request.get_json().get('password')
    
    # 查看username是否重复
    existedUser = User.query.filter_by(username=username).first()
    if existedUser != None:
        return error(message='当前用户名已存在!')
    
    # 对密码进行加密
    encoded_password = encrypt_password(password)
    user = User(username,encoded_password)
    
    db.session.add(user)
    db.session.commit()
    
    # 生成jwt 设置有效时间为24小时
    payload = {
        'user': user.to_dict(),
        'exp': datetime.datetime.utcnow() + datetime.timedelta(hours=24)
    }
    token = jwt.encode(payload, jwt_secret_key, algorithm='HS256')

    # 添加一条日志
    log = Log(username,'用户注册')
    db.session.add(log)
    db.session.commit()
    
    return success(message='注册成功',data=token)
    
"""
用户登录
"""
@loginController.route('/login',methods=['POST'])
def login():
    username = request.get_json().get('username')
    password = request.get_json().get('password')
    
    # 查询出对应用户
    user = User.query.filter_by(username=username).first()
    if user == None:
        return error(message='登陆失败，当前用户不存在！')
    # 对数据库中的密码解密
    decodedPassword = decrypt_password(user.password)
    if password != decodedPassword:
        return error(message='登陆失败，输入密码错误！')
    # 生成jwt 设置有效时间为24小时
    payload = {
        'user': user.to_dict(),
        'exp': datetime.datetime.utcnow() + datetime.timedelta(hours=24)
    }
    token = jwt.encode(payload, jwt_secret_key, algorithm='HS256')
    # 更新上次登录时间
    nowTime = datetime.datetime.now()
    User.query.filter_by(id=user.id).update({'update_time': nowTime})
    db.session.commit()

    # 添加一条日志
    log = Log(username,'用户登录')
    db.session.add(log)
    db.session.commit()

    return success(message='登陆成功',data=token)

"""
判断token是否过期
"""
@loginController.route('checkToken',methods=['GET'])
def checkToken():
    # 获取token
    token = request.cookies.get('token')
    if not token:
        token = request.headers.get('token')
    if not token:
        return authority(message='鉴权失败，请先登录！')
    
    # 校验token
    try:
        decoded_payload = jwt.decode(token, jwt_secret_key, algorithms=['HS256'])
    except jwt.ExpiredSignatureError:
        return authority(message='token已过期，请重新登录！')
    except jwt.InvalidTokenError:
        return authority(message='无效token')
    return success()

"""
获取用户信息
"""
@loginController.route('/getUserInfo',methods=['GET'])
def getUserInfo():
    token = request.cookies.get('token')
    if not token:
        token = request.headers.get('token')
    if not token:
        return authority(message='鉴权失败，请先登录！')
    try:
        decoded_payload = jwt.decode(token, jwt_secret_key, algorithms=['HS256'])
        return success(message='token解析成功',data=decoded_payload['user'])
    except jwt.ExpiredSignatureError:
        return authority(message='token已过期，请重新登录！')
    except jwt.InvalidTokenError:
        return authority(message='无效token')

"""
获取全部用户信息
"""
@loginController.route('/getAllUserInfo',methods=['GET'])
def getAllUserInfo():
    userList = User.query.all()
    dataList = []
    for user in userList:
        dataList.append(user.to_dict())
    return success(message='获取用户信息成功',data=dataList)

"""
编辑用户信息
"""
@loginController.route('/editUserInfo',methods=['PUT'])
def editUserInfo():
    id = request.get_json().get('id')
    username = request.get_json().get('username')
    role = request.get_json().get('role')

    user = User.query.filter_by(id=id).first()
    if user == None:
        return error(message='目标用户不存在')

    User.query.filter_by(id=id).update({'username': username, 'role': role})
    db.session.commit()

    # 添加一条日志
    nowUserInfo = getNowUserInfo()
    log = Log(nowUserInfo['username'],'修改用户信息')
    db.session.add(log)
    db.session.commit()
    
    return success(message='编辑用户信息成功')

"""
添加用户信息
"""
@loginController.route('/addUserInfo',methods=['POST'])
def addUserInfo():
    username = request.get_json().get('username')
    role = request.get_json().get('role')

    encodedPassword = encrypt_password(DEFAULT_PASSWORD)
    user = User(username,encodedPassword,role)

    db.session.add(user)
    db.session.commit()

    # 添加一条日志
    nowUserInfo = getNowUserInfo()
    log = Log(nowUserInfo['username'],'新增用户信息')
    db.session.add(log)
    db.session.commit()
    
    return success(message='用户添加成功')

"""
删除用户
"""
@loginController.route('/deleteUseInfo',methods=['DELETE'])
def deleteInfo():
    id = request.args.get('id')
    user = User.query.filter_by(id=id).first()
    if user == None:
        return error(message='目标用户不存在')
    
    db.session.delete(user)
    db.session.commit()

    # 添加一条日志
    nowUserInfo = getNowUserInfo()
    log = Log(nowUserInfo['username'],'删除用户信息')
    db.session.add(log)
    db.session.commit()

    return success(message='删除成功')

"""
导出用户列表
"""
@loginController.route('/exportUserInfo',methods=['GET'])
def exportUserInfo():
    userList = User.query.all()

    idList = []
    usernameList = []
    roleList = []

    for user in userList:
        idList.append(user.id)
        usernameList.append(user.username)
        if user.role == 0:
            roleText = '普通用户'
        if user.role == 1:
            roleText = '管理员'
        roleList.append(roleText)
    
    df = pd.DataFrame({"用户编号":idList,"用户名":usernameList,"用户身份":roleList})

    csv_buffer = BytesIO()
    df.to_csv(csv_buffer, index=False, encoding='utf-8-sig')
    csv_buffer.seek(0)
    
    return send_file(
        csv_buffer,
        mimetype='text/csv',
        as_attachment=True,
        download_name='用户表.csv'
    )

def getNowUserInfo():
    token = request.cookies.get('token')
    if not token:
        token = request.headers.get('token')
    decoded_payload = jwt.decode(token, jwt_secret_key, algorithms=['HS256'])
    return decoded_payload['user']